/**
 * <copyright>
 * </copyright>
 *
 * $Id$
 */
package ms.jasim.model.impl;

import java.util.ArrayList;
import java.util.List;

import ms.jasim.framework.IDescriptorProvider;
import ms.jasim.framework.JasimFramework;
import ms.jasim.model.Actor;
import ms.jasim.model.ActorList;
import ms.jasim.model.Capacity;
import ms.jasim.model.Decomposition;
import ms.jasim.model.EvaluatorList;
import ms.jasim.model.Goal;
import ms.jasim.model.GoalList;
import ms.jasim.model.GoalRequest;
import ms.jasim.model.JasimModel;
import ms.jasim.model.ModelPackage;
import ms.jasim.model.event.EventModel;
import ms.jasim.model.event.ModificationType;
import ms.jasim.model.event.impl.EventModelImpl;
import ms.jasim.model.items.Item;
import ms.jasim.model.items.ItemList;
import ms.jasim.model.items.PropertyDescriptor;
import ms.jasim.model.items.PropertyDescriptorList;
import ms.jasim.model.items.PropertyList;
import ms.jasim.model.items.impl.IntItemImpl;
import ms.jasim.model.items.impl.ItemListImpl;
import ms.jasim.pddl.PddlObject;
import ms.jasim.pddl.PddlObjectType;
import ms.jasim.pddl.PddlPredicate;
import ms.jasim.pddl.PddlProblem;
import ms.jasim.pddl.PddlSolution.PddlAction;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;

/**
 * <!-- begin-user-doc --> An implementation of the model object '
 * <em><b>Jasim Model</b></em>'. <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link ms.jasim.model.impl.JasimModelImpl#getTitle <em>Title</em>}</li>
 *   <li>{@link ms.jasim.model.impl.JasimModelImpl#getMetric <em>Metric</em>}</li>
 *   <li>{@link ms.jasim.model.impl.JasimModelImpl#getActors <em>Actors</em>}</li>
 *   <li>{@link ms.jasim.model.impl.JasimModelImpl#getGoals <em>Goals</em>}</li>
 *   <li>{@link ms.jasim.model.impl.JasimModelImpl#getEvaluators <em>Evaluators</em>}</li>
 *   <li>{@link ms.jasim.model.impl.JasimModelImpl#getOptions <em>Options</em>}</li>
 *   <li>{@link ms.jasim.model.impl.JasimModelImpl#getEventModel <em>Event Model</em>}</li>
 *   <li>{@link ms.jasim.model.impl.JasimModelImpl#getDefaultActorProperties <em>Default Actor Properties</em>}</li>
 *   <li>{@link ms.jasim.model.impl.JasimModelImpl#getDefaultGoalProperties <em>Default Goal Properties</em>}</li>
 *   <li>{@link ms.jasim.model.impl.JasimModelImpl#getDefaultCapacityProperties <em>Default Capacity Properties</em>}</li>
 *   <li>{@link ms.jasim.model.impl.JasimModelImpl#getActorDescriptors <em>Actor Descriptors</em>}</li>
 *   <li>{@link ms.jasim.model.impl.JasimModelImpl#getGoalDescriptors <em>Goal Descriptors</em>}</li>
 *   <li>{@link ms.jasim.model.impl.JasimModelImpl#getCapacityDescriptors <em>Capacity Descriptors</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class JasimModelImpl extends ModelObjectImpl implements JasimModel {
	/**
	 * The default value of the '{@link #getTitle() <em>Title</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getTitle()
	 * @generated
	 * @ordered
	 */
	protected static final String TITLE_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getTitle() <em>Title</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getTitle()
	 * @generated
	 * @ordered
	 */
	protected String title = TITLE_EDEFAULT;

	/**
	 * The default value of the '{@link #getMetric() <em>Metric</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getMetric()
	 * @generated
	 * @ordered
	 */
	protected static final String METRIC_EDEFAULT = "maximize (rt_plan_quality)";

	/**
	 * The cached value of the '{@link #getMetric() <em>Metric</em>}' attribute.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getMetric()
	 * @generated
	 * @ordered
	 */
	protected String metric = METRIC_EDEFAULT;

	/**
	 * The cached value of the '{@link #getActors() <em>Actors</em>}' containment reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getActors()
	 * @generated
	 * @ordered
	 */
	protected ActorList actors;

	/**
	 * The cached value of the '{@link #getGoals() <em>Goals</em>}' containment reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getGoals()
	 * @generated
	 * @ordered
	 */
	protected GoalList goals;

	/**
	 * The cached value of the '{@link #getEvaluators() <em>Evaluators</em>}' containment reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getEvaluators()
	 * @generated
	 * @ordered
	 */
	protected EvaluatorList evaluators;

	/**
	 * The cached value of the '{@link #getOptions() <em>Options</em>}' containment reference.
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @see #getOptions()
	 * @generated
	 * @ordered
	 */
	protected ItemList options;

	/**
	 * The cached value of the '{@link #getEventModel() <em>Event Model</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getEventModel()
	 * @generated
	 * @ordered
	 */
	protected EventModel eventModel;

	/**
	 * The cached value of the '{@link #getDefaultActorProperties() <em>Default Actor Properties</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDefaultActorProperties()
	 * @generated
	 * @ordered
	 */
	protected PropertyList defaultActorProperties;

	/**
	 * The cached value of the '{@link #getDefaultGoalProperties() <em>Default Goal Properties</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDefaultGoalProperties()
	 * @generated
	 * @ordered
	 */
	protected PropertyList defaultGoalProperties;

	/**
	 * The cached value of the '{@link #getDefaultCapacityProperties() <em>Default Capacity Properties</em>}' containment reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDefaultCapacityProperties()
	 * @generated
	 * @ordered
	 */
	protected PropertyList defaultCapacityProperties;

	private ArrayList<Object[]> postCommand;

	private URI uri;

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	protected JasimModelImpl() {
		super();
		setGoals(new GoalListImpl());
		setActors(new ActorListImpl());
		setEvaluators(new EvaluatorListImpl());
		setOptions(new ItemListImpl());
		setEventModel(new EventModelImpl());
		
		goals.setPredefined(true);
		actors.setPredefined(true);
		evaluators.setPredefined(true);
		options.setPredefined(true);
		eventModel.setPredefined(true);
		
		options.setName("Options");
		populateOptions();
	}

	protected void populateOptions() {
		ItemList pddlOpt = (ItemList) options.get("PddlOptions");
		if (pddlOpt == null)
			options.getItem().add(pddlOpt = new ItemListImpl("PddlOptions"));
		if (pddlOpt.get("work_load_coeff") == null)
			pddlOpt.getItem().add(new IntItemImpl("work_load_coeff", 1));
		if (pddlOpt.get("satisfaction_coeff") == null)
			pddlOpt.getItem().add(new IntItemImpl("satisfaction_coeff", 1));
			
		
		ItemList plannerOpt = (ItemList) options.get("PlannerOptions");
		if (plannerOpt == null)
			options.getItem().add(plannerOpt = new ItemListImpl("PlannerOptions"));
		if (plannerOpt.get("MaxSolution") == null)
			plannerOpt.getItem().add(new IntItemImpl("MaxSolution", 1));
		if (plannerOpt.get("MaxCpuTime") == null)
			plannerOpt.getItem().add(new IntItemImpl("MaxCpuTime", 1));
	}
	
	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return ModelPackage.Literals.JASIM_MODEL;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setTitle(String newTitle) {
		String oldTitle = title;
		title = newTitle;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__TITLE, oldTitle, title));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public String getMetric() {
		return metric;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public void setMetric(String newMetric) {
		String oldMetric = metric;
		metric = newMetric;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__METRIC, oldMetric, metric));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public ActorList getActors() {
		return actors;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public NotificationChain basicSetActors(ActorList newActors,
			NotificationChain msgs) {
		ActorList oldActors = actors;
		actors = newActors;
		actors.setPredefined(true);
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__ACTORS, oldActors, newActors);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	public void setActors(ActorList newActors) {
		if (newActors == null) 
			return;
		
		if (newActors != actors) {
			NotificationChain msgs = null;
			if (actors != null)
				msgs = ((InternalEObject)actors).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__ACTORS, null, msgs);
			if (newActors != null)
				msgs = ((InternalEObject)newActors).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__ACTORS, null, msgs);
			msgs = basicSetActors(newActors, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__ACTORS, newActors, newActors));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public GoalList getGoals() {
		return goals;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public NotificationChain basicSetGoals(GoalList newGoals,
			NotificationChain msgs) {
		GoalList oldGoals = goals;
		goals = newGoals;
		goals.setPredefined(true);
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__GOALS, oldGoals, newGoals);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	public void setGoals(GoalList newGoals) {
		if (newGoals != goals) {
			NotificationChain msgs = null;
			if (goals != null)
				msgs = ((InternalEObject)goals).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__GOALS, null, msgs);
			if (newGoals != null)
				msgs = ((InternalEObject)newGoals).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__GOALS, null, msgs);
			msgs = basicSetGoals(newGoals, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__GOALS, newGoals, newGoals));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public EvaluatorList getEvaluators() {
		return evaluators;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public NotificationChain basicSetEvaluators(EvaluatorList newEvaluators,
			NotificationChain msgs) {
		EvaluatorList oldEvaluators = evaluators;
		evaluators = newEvaluators;
		evaluators.setPredefined(true);
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__EVALUATORS, oldEvaluators, newEvaluators);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	public void setEvaluators(EvaluatorList newEvaluators) {
		if (newEvaluators == null)
			return;
		
		if (newEvaluators != evaluators) {
			NotificationChain msgs = null;
			if (evaluators != null)
				msgs = ((InternalEObject)evaluators).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__EVALUATORS, null, msgs);
			if (newEvaluators != null)
				msgs = ((InternalEObject)newEvaluators).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__EVALUATORS, null, msgs);
			msgs = basicSetEvaluators(newEvaluators, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__EVALUATORS, newEvaluators, newEvaluators));
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public ItemList getOptions() {
		return options;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 */
	public NotificationChain basicSetOptions(ItemList newOptions,
			NotificationChain msgs) {
		ItemList oldOptions = options;
		options = newOptions;
		options.setName("Options");
		options.setPredefined(true);
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__OPTIONS, oldOptions, newOptions);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	public void setOptions(ItemList newOptions) {
		
		if (newOptions != options) {
			newOptions.setName("Options");
			NotificationChain msgs = null;
			if (options != null)
				msgs = ((InternalEObject)options).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__OPTIONS, null, msgs);
			if (newOptions != null)
				msgs = ((InternalEObject)newOptions).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__OPTIONS, null, msgs);
			msgs = basicSetOptions(newOptions, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__OPTIONS, newOptions, newOptions));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EventModel getEventModel() {
		return eventModel;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	public NotificationChain basicSetEventModel(EventModel newEventModel, NotificationChain msgs) {
		EventModel oldEventModel = eventModel;
		eventModel = newEventModel;
		eventModel.setPredefined(true);
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__EVENT_MODEL, oldEventModel, newEventModel);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	public void setEventModel(EventModel newEventModel) {
		if (newEventModel == null)
			return;
		
		if (newEventModel != eventModel) {
			NotificationChain msgs = null;
			if (eventModel != null)
				msgs = ((InternalEObject)eventModel).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__EVENT_MODEL, null, msgs);
			if (newEventModel != null)
				msgs = ((InternalEObject)newEventModel).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__EVENT_MODEL, null, msgs);
			msgs = basicSetEventModel(newEventModel, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__EVENT_MODEL, newEventModel, newEventModel));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public PropertyList getDefaultActorProperties() {
		return defaultActorProperties;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public NotificationChain basicSetDefaultActorProperties(PropertyList newDefaultActorProperties, NotificationChain msgs) {
		PropertyList oldDefaultActorProperties = defaultActorProperties;
		defaultActorProperties = newDefaultActorProperties;
		if (defaultActorProperties != null) {
			defaultActorProperties.setName("Default Actor Properties");
			defaultActorProperties.setClazz(Actor.class);
			defaultActorProperties.setReservedName(true);
		}
		
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__DEFAULT_ACTOR_PROPERTIES, oldDefaultActorProperties, newDefaultActorProperties);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDefaultActorProperties(PropertyList newDefaultActorProperties) {
		if (newDefaultActorProperties != defaultActorProperties) {
			NotificationChain msgs = null;
			if (defaultActorProperties != null)
				msgs = ((InternalEObject)defaultActorProperties).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__DEFAULT_ACTOR_PROPERTIES, null, msgs);
			if (newDefaultActorProperties != null)
				msgs = ((InternalEObject)newDefaultActorProperties).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__DEFAULT_ACTOR_PROPERTIES, null, msgs);
			msgs = basicSetDefaultActorProperties(newDefaultActorProperties, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__DEFAULT_ACTOR_PROPERTIES, newDefaultActorProperties, newDefaultActorProperties));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public PropertyList getDefaultGoalProperties() {
		return defaultGoalProperties;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public NotificationChain basicSetDefaultGoalProperties(PropertyList newDefaultGoalProperties, NotificationChain msgs) {
		PropertyList oldDefaultGoalProperties = defaultGoalProperties;
		defaultGoalProperties = newDefaultGoalProperties;
		if (defaultGoalProperties != null) {
			defaultGoalProperties.setName("Default Goal Properties");
			defaultGoalProperties.setClazz(Goal.class);
			defaultGoalProperties.setReadonly(true);
		}
		
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__DEFAULT_GOAL_PROPERTIES, oldDefaultGoalProperties, newDefaultGoalProperties);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDefaultGoalProperties(PropertyList newDefaultGoalProperties) {
		if (newDefaultGoalProperties != defaultGoalProperties) {
			NotificationChain msgs = null;
			if (defaultGoalProperties != null)
				msgs = ((InternalEObject)defaultGoalProperties).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__DEFAULT_GOAL_PROPERTIES, null, msgs);
			if (newDefaultGoalProperties != null)
				msgs = ((InternalEObject)newDefaultGoalProperties).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__DEFAULT_GOAL_PROPERTIES, null, msgs);
			msgs = basicSetDefaultGoalProperties(newDefaultGoalProperties, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__DEFAULT_GOAL_PROPERTIES, newDefaultGoalProperties, newDefaultGoalProperties));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public PropertyList getDefaultCapacityProperties() {
		return defaultCapacityProperties;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public NotificationChain basicSetDefaultCapacityProperties(PropertyList newDefaultCapacityProperties, NotificationChain msgs) {
		PropertyList oldDefaultCapacityProperties = defaultCapacityProperties;
		defaultCapacityProperties = newDefaultCapacityProperties;
		if (defaultCapacityProperties != null) {
			defaultCapacityProperties.setName("Default Capacity Properties");
			defaultCapacityProperties.setClazz(Capacity.class);
			defaultCapacityProperties.setReservedName(true);
		}
		if (eNotificationRequired()) {
			ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__DEFAULT_CAPACITY_PROPERTIES, oldDefaultCapacityProperties, newDefaultCapacityProperties);
			if (msgs == null) msgs = notification; else msgs.add(notification);
		}
		return msgs;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setDefaultCapacityProperties(PropertyList newDefaultCapacityProperties) {
		if (newDefaultCapacityProperties != defaultCapacityProperties) {
			NotificationChain msgs = null;
			if (defaultCapacityProperties != null)
				msgs = ((InternalEObject)defaultCapacityProperties).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__DEFAULT_CAPACITY_PROPERTIES, null, msgs);
			if (newDefaultCapacityProperties != null)
				msgs = ((InternalEObject)newDefaultCapacityProperties).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - ModelPackage.JASIM_MODEL__DEFAULT_CAPACITY_PROPERTIES, null, msgs);
			msgs = basicSetDefaultCapacityProperties(newDefaultCapacityProperties, msgs);
			if (msgs != null) msgs.dispatch();
		}
		else if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ModelPackage.JASIM_MODEL__DEFAULT_CAPACITY_PROPERTIES, newDefaultCapacityProperties, newDefaultCapacityProperties));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public PropertyDescriptorList getActorDescriptors() {
		PropertyDescriptorList actorDescriptors = basicGetActorDescriptors();
		return actorDescriptors != null && actorDescriptors.eIsProxy() ? (PropertyDescriptorList)eResolveProxy((InternalEObject)actorDescriptors) : actorDescriptors;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public PropertyDescriptorList basicGetActorDescriptors() {
		IDescriptorProvider provider = JasimFramework.getDescriptorProvider(null);
		return provider != null ? provider.getPropertyDescriptorList(Actor.class) : null;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public PropertyDescriptorList getGoalDescriptors() {
		PropertyDescriptorList goalDescriptors = basicGetGoalDescriptors();
		return goalDescriptors != null && goalDescriptors.eIsProxy() ? (PropertyDescriptorList)eResolveProxy((InternalEObject)goalDescriptors) : goalDescriptors;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public PropertyDescriptorList basicGetGoalDescriptors() {
		IDescriptorProvider provider = JasimFramework.getDescriptorProvider(null);
		return provider != null ? provider.getPropertyDescriptorList(Goal.class) : null;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public PropertyDescriptorList getCapacityDescriptors() {
		PropertyDescriptorList capacityDescriptors = basicGetCapacityDescriptors();
		return capacityDescriptors != null && capacityDescriptors.eIsProxy() ? (PropertyDescriptorList)eResolveProxy((InternalEObject)capacityDescriptors) : capacityDescriptors;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public PropertyDescriptorList basicGetCapacityDescriptors() {
		IDescriptorProvider provider = JasimFramework.getDescriptorProvider(null);
		return provider != null ? provider.getPropertyDescriptorList(Capacity.class) : null;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	public URI getURI() {
		return this.uri;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 */
	public void setURI(URI uri) {
		this.uri = uri;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public PropertyDescriptor findPropertyDescriptor(Class<?> clazz, String nameOrPddlFunction) {
		IDescriptorProvider provider = JasimFramework.getDescriptorProvider(null);
		if (provider == null)
			return null;
		PropertyDescriptorList list = provider.getPropertyDescriptorList(clazz);
		for (PropertyDescriptor d: list)
			if (String.CASE_INSENSITIVE_ORDER.compare(nameOrPddlFunction, d.getPddlPredicate()) == 0 ||
				(d.getItem() != null && d.getItem().getName().equalsIgnoreCase(nameOrPddlFunction)))
				return d;
		return null;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd,
			int featureID, NotificationChain msgs) {
		switch (featureID) {
			case ModelPackage.JASIM_MODEL__ACTORS:
				return basicSetActors(null, msgs);
			case ModelPackage.JASIM_MODEL__GOALS:
				return basicSetGoals(null, msgs);
			case ModelPackage.JASIM_MODEL__EVALUATORS:
				return basicSetEvaluators(null, msgs);
			case ModelPackage.JASIM_MODEL__OPTIONS:
				return basicSetOptions(null, msgs);
			case ModelPackage.JASIM_MODEL__EVENT_MODEL:
				return basicSetEventModel(null, msgs);
			case ModelPackage.JASIM_MODEL__DEFAULT_ACTOR_PROPERTIES:
				return basicSetDefaultActorProperties(null, msgs);
			case ModelPackage.JASIM_MODEL__DEFAULT_GOAL_PROPERTIES:
				return basicSetDefaultGoalProperties(null, msgs);
			case ModelPackage.JASIM_MODEL__DEFAULT_CAPACITY_PROPERTIES:
				return basicSetDefaultCapacityProperties(null, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case ModelPackage.JASIM_MODEL__TITLE:
				return getTitle();
			case ModelPackage.JASIM_MODEL__METRIC:
				return getMetric();
			case ModelPackage.JASIM_MODEL__ACTORS:
				return getActors();
			case ModelPackage.JASIM_MODEL__GOALS:
				return getGoals();
			case ModelPackage.JASIM_MODEL__EVALUATORS:
				return getEvaluators();
			case ModelPackage.JASIM_MODEL__OPTIONS:
				return getOptions();
			case ModelPackage.JASIM_MODEL__EVENT_MODEL:
				return getEventModel();
			case ModelPackage.JASIM_MODEL__DEFAULT_ACTOR_PROPERTIES:
				return getDefaultActorProperties();
			case ModelPackage.JASIM_MODEL__DEFAULT_GOAL_PROPERTIES:
				return getDefaultGoalProperties();
			case ModelPackage.JASIM_MODEL__DEFAULT_CAPACITY_PROPERTIES:
				return getDefaultCapacityProperties();
			case ModelPackage.JASIM_MODEL__ACTOR_DESCRIPTORS:
				if (resolve) return getActorDescriptors();
				return basicGetActorDescriptors();
			case ModelPackage.JASIM_MODEL__GOAL_DESCRIPTORS:
				if (resolve) return getGoalDescriptors();
				return basicGetGoalDescriptors();
			case ModelPackage.JASIM_MODEL__CAPACITY_DESCRIPTORS:
				if (resolve) return getCapacityDescriptors();
				return basicGetCapacityDescriptors();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case ModelPackage.JASIM_MODEL__TITLE:
				setTitle((String)newValue);
				return;
			case ModelPackage.JASIM_MODEL__METRIC:
				setMetric((String)newValue);
				return;
			case ModelPackage.JASIM_MODEL__ACTORS:
				setActors((ActorList)newValue);
				return;
			case ModelPackage.JASIM_MODEL__GOALS:
				setGoals((GoalList)newValue);
				return;
			case ModelPackage.JASIM_MODEL__EVALUATORS:
				setEvaluators((EvaluatorList)newValue);
				return;
			case ModelPackage.JASIM_MODEL__OPTIONS:
				setOptions((ItemList)newValue);
				return;
			case ModelPackage.JASIM_MODEL__EVENT_MODEL:
				setEventModel((EventModel)newValue);
				return;
			case ModelPackage.JASIM_MODEL__DEFAULT_ACTOR_PROPERTIES:
				setDefaultActorProperties((PropertyList)newValue);
				return;
			case ModelPackage.JASIM_MODEL__DEFAULT_GOAL_PROPERTIES:
				setDefaultGoalProperties((PropertyList)newValue);
				return;
			case ModelPackage.JASIM_MODEL__DEFAULT_CAPACITY_PROPERTIES:
				setDefaultCapacityProperties((PropertyList)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case ModelPackage.JASIM_MODEL__TITLE:
				setTitle(TITLE_EDEFAULT);
				return;
			case ModelPackage.JASIM_MODEL__METRIC:
				setMetric(METRIC_EDEFAULT);
				return;
			case ModelPackage.JASIM_MODEL__ACTORS:
				setActors((ActorList)null);
				return;
			case ModelPackage.JASIM_MODEL__GOALS:
				setGoals((GoalList)null);
				return;
			case ModelPackage.JASIM_MODEL__EVALUATORS:
				setEvaluators((EvaluatorList)null);
				return;
			case ModelPackage.JASIM_MODEL__OPTIONS:
				setOptions((ItemList)null);
				return;
			case ModelPackage.JASIM_MODEL__EVENT_MODEL:
				setEventModel((EventModel)null);
				return;
			case ModelPackage.JASIM_MODEL__DEFAULT_ACTOR_PROPERTIES:
				setDefaultActorProperties((PropertyList)null);
				return;
			case ModelPackage.JASIM_MODEL__DEFAULT_GOAL_PROPERTIES:
				setDefaultGoalProperties((PropertyList)null);
				return;
			case ModelPackage.JASIM_MODEL__DEFAULT_CAPACITY_PROPERTIES:
				setDefaultCapacityProperties((PropertyList)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case ModelPackage.JASIM_MODEL__TITLE:
				return TITLE_EDEFAULT == null ? title != null : !TITLE_EDEFAULT.equals(title);
			case ModelPackage.JASIM_MODEL__METRIC:
				return METRIC_EDEFAULT == null ? metric != null : !METRIC_EDEFAULT.equals(metric);
			case ModelPackage.JASIM_MODEL__ACTORS:
				return actors != null;
			case ModelPackage.JASIM_MODEL__GOALS:
				return goals != null;
			case ModelPackage.JASIM_MODEL__EVALUATORS:
				return evaluators != null;
			case ModelPackage.JASIM_MODEL__OPTIONS:
				return options != null;
			case ModelPackage.JASIM_MODEL__EVENT_MODEL:
				return eventModel != null;
			case ModelPackage.JASIM_MODEL__DEFAULT_ACTOR_PROPERTIES:
				return defaultActorProperties != null;
			case ModelPackage.JASIM_MODEL__DEFAULT_GOAL_PROPERTIES:
				return defaultGoalProperties != null;
			case ModelPackage.JASIM_MODEL__DEFAULT_CAPACITY_PROPERTIES:
				return defaultCapacityProperties != null;
			case ModelPackage.JASIM_MODEL__ACTOR_DESCRIPTORS:
				return basicGetActorDescriptors() != null;
			case ModelPackage.JASIM_MODEL__GOAL_DESCRIPTORS:
				return basicGetGoalDescriptors() != null;
			case ModelPackage.JASIM_MODEL__CAPACITY_DESCRIPTORS:
				return basicGetCapacityDescriptors() != null;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (Title: ");
		result.append(title);
		result.append(", Metric: ");
		result.append(metric);
		result.append(')');
		return result.toString();
	}

	@Override
	public PddlProblem generatePddlProblem() {
		
		PddlProblem pddl = new PddlProblem(this);
		Item optItem = options.get("PddlOptions");
		
		if (optItem != null && optItem instanceof ItemList)
			for (Item opt: (ItemList)optItem)
				pddl.facts.add(new PddlPredicate(PddlPredicate.ASSIGN, 
							new PddlPredicate(opt.getName()), 
							opt.getValue(null)));
		
		IDescriptorProvider provider = JasimFramework.getDescriptorProvider(null);
		
		// generate goal objects
		
		List<PropertyDescriptor> goalDescriptors = provider != null ? provider.getPropertyDescriptors(Goal.class) : null;		
		for (Goal g : this.getGoals()) {
			PddlObject pddlGoal = new PddlObject(g.getName(), PddlObjectType.T_GOAL);
			pddl.objects.add(pddlGoal);
			
			/*pddl.facts.add(new PddlPredicate(PddlPredicate.ASSIGN, 
					new PddlPredicate(PddlPredicate.MAX_SATISFACTION_DEGREE, pddlGoal), 
					g.getMaxSatisfaction()));*/
			
			if (goalDescriptors != null)
				for (PropertyDescriptor d: goalDescriptors)
					if (d.getPddlPredicate() != null && d.getPddlPredicate().length() > 0) {
						Item item = g.getProperties().get(d.getName(), this.getDefaultGoalProperties(), d);
						if (item != null)
							pddl.facts.add(new PddlPredicate(PddlPredicate.ASSIGN, 
									new PddlPredicate(d.getPddlPredicate(), pddlGoal), item.getValue(null)));
					}			
			
			String[][] decomposePredicates = {
				{ PddlPredicate.AND_DECOMPOSE2, PddlPredicate.AND_DECOMPOSE3 },
				{ PddlPredicate.OR_DECOMPOSE2, PddlPredicate.AND_DECOMPOSE3 }
			};
			
			for (Decomposition de : g.getDecomposition()) {
				PddlPredicate pred = new PddlPredicate();
				
				int size = de.getSubGoals().size();
				
				if (size >= 2 && size <= 3)
					pred.setFunctor(decomposePredicates[de.getType().getValue()][size - 2]);
				
				pred.getArgs().add(pddlGoal);
				for (Goal sg: de.getSubGoals())
					pred.getArgs().add(sg.getName());
				pddl.facts.add(pred);
			}
		}
		
		// generate actor objects
		List<PropertyDescriptor> actorDescriptors = provider != null ? provider.getPropertyDescriptors(Actor.class) : null;
		List<PropertyDescriptor> capacityDescriptors = provider != null ? provider.getPropertyDescriptors(Capacity.class) : null;
		PropertyDescriptor numInstanceDescriptor = findPropertyDescriptor(Actor.class, PddlPredicate.NUM_INSTANCE);
		
		for (Actor a : this.getActors()) {
			int numIns = (Integer) a.resolveProperty(numInstanceDescriptor).getValue(null);
			for (int i = 1; i < numIns; i ++) {
				
				PddlObject pddlActor = new PddlObject(a.getName(), PddlObjectType.T_ACTOR);
				pddl.objects.add(pddlActor);
				pddlActor.setInstanceID(i);
				
				/*pddl.facts.add(new PddlPredicate(PddlPredicate.ASSIGN,
										new PddlPredicate(PddlPredicate.MAX_WORK_LOAD, pddlActor),
										a.getMaxWorkLoad()));
				pddl.facts.add(new PddlPredicate(PddlPredicate.ASSIGN,
										new PddlPredicate(PddlPredicate.MAX_JOB_AT_HAND, pddlActor),
										a.getMaxJob()));*/
				
				if (actorDescriptors != null)
					for (PropertyDescriptor d: actorDescriptors)
						if (d.getPddlPredicate() != null && d.getPddlPredicate().length() > 0) {
							Item item = a.getProperties().get(d.getName(), this.getDefaultActorProperties(), d);
							if (item != null)
								pddl.facts.add(new PddlPredicate(PddlPredicate.ASSIGN, 
										new PddlPredicate(d.getPddlPredicate(), pddlActor), item.getValue(null)));
						}
				
				for (GoalRequest request : a.getRequests())
					if (request.getGoal() != null) {
						PddlObject pddlGoal = pddl.objects.get(request.getGoal().getName());
						pddl.facts.add(new PddlPredicate(PddlPredicate.REQUESTS, pddlActor, pddlGoal));
						pddl.goals.add(new PddlPredicate(PddlPredicate.SATISFIED, pddlGoal));
					}
				
				for (Capacity cap : a.getCapacity()) {
					PddlObject pddlGoal = pddl.objects.get(cap.getGoal().getName());
					pddl.facts.add(new PddlPredicate(PddlPredicate.CAN_PROVIDE, pddlActor, pddlGoal));
					
					/*pddl.facts.add(new PddlPredicate(PddlPredicate.ASSIGN,
							new PddlPredicate(PddlPredicate.WORK_EFFORT, pddlActor, pddlGoal),
							cap.getEffort()));
					pddl.facts.add(new PddlPredicate(PddlPredicate.ASSIGN,
							new PddlPredicate(PddlPredicate.TIME_EFFORT, pddlActor, pddlGoal),
							cap.getTime()));
					pddl.facts.add(new PddlPredicate(PddlPredicate.ASSIGN,
							new PddlPredicate(PddlPredicate.SATISFACTION_ABILITY, pddlActor, pddlGoal),
							cap.getSatisfaction()));*/
					
					if (capacityDescriptors != null)
						for (PropertyDescriptor d: capacityDescriptors)
							if (d.getPddlPredicate() != null && d.getPddlPredicate().length() > 0) {
								Item item = cap.getProperties().get(d.getName(), this.getDefaultCapacityProperties(), d);
								if (item != null)
									pddl.facts.add(new PddlPredicate(PddlPredicate.ASSIGN, 
											new PddlPredicate(d.getPddlPredicate(), pddlActor, pddlGoal), item.getValue(null)));
							}
				}
			}	
		}
		
		processPostCommand(pddl);
		
		return pddl;
	}

	private PddlProblem processPostCommand(PddlProblem pddl) {
		for (Object[] cmd : getPostProcessCommand()) {
			ModificationType type = (ModificationType) cmd[0];
			PddlPredicate pred = (PddlPredicate) cmd[1];
			switch(type) {
			case ADD_FACT:
				pddl.facts.add(pred);
				break;
			case ADD_GOAL:
				pddl.goals.add(pred);
				break;
			case REMOVE_FACT:
			case REMOVE_GOAL:
				if ((pred = pddl.findPredicate(type == ModificationType.REMOVE_FACT ? 
						pddl.facts : pddl.goals, pred, 0)) != null)
					pddl.facts.remove(pred);
				break;
			}
		}
		return pddl;
	}
	
	@Override
	public void reflectFinishedAction(PddlAction act) {
		switch (act.getFunctor()) {
		case SATISFIES:
			addPostCommand(ModificationType.ADD_FACT, 
					new PddlPredicate(PddlPredicate.PR_SATISFIES, act.getArgument(0), act.getArgument(1)));
			addPostCommand(ModificationType.ADD_FACT, 
					new PddlPredicate(PddlPredicate.SATISFIED, act.getArgument(1)));
			break;
		}
	}

	@Override
	public void addPostCommand(ModificationType type, PddlPredicate pddlPredicate) {
		getPostProcessCommand().add(new Object[] {type, pddlPredicate});
	}

	@Override
	public List<Object[]> getPostProcessCommand() {
		if (this.postCommand == null)
			this.postCommand = new ArrayList<Object[]>();
		return this.postCommand;
	}

} //JasimModelImpl
